Skip to content

Instantly share code, notes, and snippets.

@ynagatomo
Created May 20, 2024 00:38
Show Gist options
  • Save ynagatomo/50a290aee280203823221a75108976f9 to your computer and use it in GitHub Desktop.
Save ynagatomo/50a290aee280203823221a75108976f9 to your computer and use it in GitHub Desktop.
This sample shows Observable object instances with `@Observable and @State` are created many times when a view that has the property is evaluated. So avoid heavy initializations on the Observable classes.
//
// ObservableTwiceInitProblemTestApp.swift
// ObservableTwiceInitProblemTest
//
// Created by Yasuhito Nagatomo on 2024/05/20.
//
// Modified christianselig/sample-view-model-init.swift
// https://gist.github.com/christianselig/d88b1a4d1989b973689ae62d4691162f
//
// This sample shows Observable object instances with `@Observable and @State`
// are created many times when a view that has the property is evaluated.
// So avoid heavy initializations on the Observable classes.
import SwiftUI
@main
struct WindowPresentationFunApp: App {
@State var appState = AppState()
var body: some Scene {
WindowGroup {
InitialView(appState: appState)
}
}
}
struct InitialView: View {
let appState: AppState
@State private var showing = false
var body: some View {
Button(action: { showing.toggle() }, label: { Text("Tap Me")})
.sheet(isPresented: $showing) {
RootView(appState: appState)
}
}
}
struct RootView: View {
let appState: AppState
var body: some View {
VStack {
Text("Swipe down to close").padding()
SpecialView()
Button(action: { appState.show.toggle() }) {
Text("Change the show flag").padding()
}
Text("Show flag: " + (appState.show ? "True" : "False")).padding()
}
}
}
struct SpecialView: View {
@State private var viewModel = ViewModel()
var body: some View {
let _ = print("SpecialView will be evaluated.")
Text("Special stuff, VM's MyID: \(viewModel.myID)")
}
}
@Observable class AppState {
var show: Bool = false
}
@Observable class ViewModel {
let myID = UUID()
// This cannot be `lazy` when using @Observable
let attribute1: Int = {
print("Heavy Calculation #1 ...")
return 0
}()
init() {
print("✅ View model was inited ID: \(myID)")
}
deinit {
print("❌ View model was deinited ID: \(myID)")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment